﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SuperSocket;
using SuperSocket.Channel;

namespace Lawn.AppServer
{
    public class SessionManager:ISessionManager
    {
        protected ConcurrentDictionary<string, ClientInfo> ClientInfos = new ConcurrentDictionary<string, ClientInfo>();
       

        
        public SessionManager()
        {
           
          
        }

        public  async Task Closed(IAppSession session)
        {

            ClientInfo info;
            var found= ClientInfos.TryGetValue(session.SessionID, out info);
            if (found)
            {
                ClientInfos.TryRemove(session.SessionID,out info);
            }
            await Task.CompletedTask;
        }

        public async Task  Connected(IAppSession _session)
        {
            ClientInfos.TryAdd(_session.SessionID, new ClientInfo()
            {
                ClientId = _session.SessionID, Session =_session
            });

            await Task.CompletedTask;
        }

        
        
        public Task AddSessionTopic(string topic)
        {
            throw new System.NotImplementedException();
        }

        public async Task<int> GetSessionCount()
        {

            var count = ClientInfos.Keys.Count;
            return await Task.FromResult(count);
        }

        public async Task<List<IAppSession>> GetAllSession()
        {
            var data = ClientInfos.Values.Select(x=>x.Session).ToList();

            return await Task.FromResult(data);
        }

        public Task<IAppSession> GetSession(string clientId)
        {
            ClientInfo info;
            var found= ClientInfos.TryGetValue(clientId,out  info);
            if (found)
            {
                return Task.FromResult(info.Session);
            }

            return null;
        }

        public async Task Add(string clientId, string topic)
        {

            ClientInfo info;
            var found= ClientInfos.TryGetValue(clientId,out  info);
            if (!found)
            {
                info = new ClientInfo();
                ClientInfos.TryAdd(clientId, info);
            }

            if (!info.Topics.Exists(x => x == topic))
            {
                info.Topics.Add(topic);
            }

            await Task.CompletedTask;
        }

        public async Task Remove(string clientId, string topic)
        {
            ClientInfo info;
            var found= ClientInfos.TryGetValue(clientId,out  info);
            if (found)
            {
                info.Topics.Remove(topic);
            }
            await Task.CompletedTask;
        }

        public async Task<List<ClientInfo>> GetAll()
        {
            var data = ClientInfos.Values.ToList();

            return await Task.FromResult(data);

        }

        public async Task<List<ClientInfo>> GetTopic(string topic)
        {
            var data = ClientInfos.Values.ToList().Where(x=>x.Topics.Contains(topic)).ToList();
            
            return await Task.FromResult(data);
            
        }
    }
}